package com.rabbitmq.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @Auther: liyanhao
 * @Description: 交换机确认回调接口
 * @Date: 2022/5/12 17:24
 * @Version: v1.0
 */
@Component
@Slf4j
public class MyCallBack implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    //注入
    @PostConstruct
    public void init(){
        //把内部类接口注入
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    /**
     * 交换机确认回调方法
     * 1 发消息 交换机收到了 回调
     * 1.1 correlationData 保存回调消息的ID及相关信息
     * 1.2 交换机收到消息 true
     * 1.3 cause null
     * 2 发消息 交换机接收失败了  回调
     * 2.1 correlationData 保存回调消息的ID以及相关信息
     * 2.2 交换机收到信息 ack=false
     * 2.3 cause 失败的原因
     *
     * @param correlationData
     * @param ack
     * @param cause
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        String id = "";
        if (correlationData != null) {
            id = correlationData.getId();
        }
        if (ack) {
            log.info("交换机已经收到了消息id：{}", id);
        } else {
            log.info("交换机还没有收到消息id：{}，原因为：{}", id, cause);
        }
    }

    /**
     * 当消息不可达的时候将消息返回给生产者
     * 只有目的不可达目的地 才进行回退
     * @param message
     * @param replyCode
     * @param replyText
     * @param exchange
     * @param routingkey
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingkey) {
        log.error("消息：{}，被交换机：{}退回，退回原因：{},路由Key：{}",
                new String(message.getBody()), exchange, replyText, routingkey);
    }


}
